package com.sanbi.shield.server.shield;

import java.util.HashMap;
import java.util.Map;

/**
 * 业务上下文
 *
 * @author XiaoQingqing
 * @since 2024/07/27
 */
class ShieldContext {
    /**
     * 上下文内容
     */
    private static final ThreadLocal<Map<String, Object>> CONTENT = new ThreadLocal<>();
    /**
     * 当前用户ID
     */
    private static final String CURRENT_USER_ID = "CURRENT_USER_ID";
    /**
     * 通用上下文键
     */
    private static final String COMMON_CONTEXT_KEY = "COMMON_CONTEXT";

    /**
     * 获取用户ID
     *
     * @return 用户ID
     */
    static Long getUserId(){
        return get(CURRENT_USER_ID);
    }

    /**
     * 设置访问通行证
     *
     * @param userId 用户ID
     */
    static void setUserId(Long userId){
        set(CURRENT_USER_ID, userId);
    }

    /**
     * 添加上下文
     *
     * @param key   键
     * @param value 值
     * @param <T>   值类型
     */
    static <T> void pushToContext(Object key, T value) {
        Map<Object, Object> contextMap = get(COMMON_CONTEXT_KEY);
        if(null == contextMap){
            contextMap = new HashMap<>();
            set(COMMON_CONTEXT_KEY, contextMap);
        }
        contextMap.put(key, value);
    }

    /**
     * 获取上下文
     *
     * @param key 键
     * @return 值
     * @param <T> 值类型
     */
    @SuppressWarnings("unchecked")
    static <T> T getFromContext(Object key) {
        Map<Object, Object> contextMap = get(COMMON_CONTEXT_KEY);
        return null == contextMap ? null : (T)contextMap.get(key);
    }

    /**
     * 设置值
     *
     * @param key   键
     * @param value 值
     * @param <T>   值类型
     */
    private static <T> void set(String key, T value){
        Map<String, Object> contextMap = CONTENT.get();
        if(null == contextMap){
            contextMap = new HashMap<>();
            CONTENT.set(contextMap);
        }
        contextMap.put(key, value);
    }

    /**
     * 获取值
     *
     * @param key 键
     * @return 值
     * @param <T> 值类型
     */
    @SuppressWarnings("unchecked")
    private static <T> T get(String key){
        Map<String, Object> contextMap = CONTENT.get();
        return null == contextMap ? null : (T)contextMap.get(key);
    }

    /**
     * 清空上下文
     */
    static void clear(){
        CONTENT.remove();
    }

}
